home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / RAND / DVIEW000.LZH / VIEW_UT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-10  |  7.3 KB  |  288 lines

  1. /********************************************************************
  2.  FILENAME: VIEW_UT.CPP
  3.  AUTHOR  : JAKE HILL
  4.  DATE    : 12/1/94
  5.  
  6.  Copyright (c) 1994 by Jake Hill:
  7.  If you use any part of this code in your own project, please credit
  8.  me in your documentation and source code.  Thanks.
  9. ********************************************************************/
  10.  
  11. #define STEP_HEIGHT 24
  12.  
  13. #define C
  14.  
  15. #include "view.h"
  16. #include "trig.h"
  17.  
  18. extern short MaxNode;
  19.  
  20. extern short chksect;
  21. extern short tellsect;
  22.  
  23. extern short player_ssector;
  24. extern short last_height;
  25.  
  26. /* This function returns TRUE it the player is on the right
  27.  * of the node indexed by node_num.
  28.  */
  29.  
  30. char OnRightNode(short node_num)
  31. {
  32.    node *ThisNode = PNode_Array[node_num];
  33.    long x1 = ThisNode->x;
  34.    long y1 = ThisNode->y;
  35.    long x2 = x1 + ThisNode->dx;
  36.    long y2 = y1 + ThisNode->dy;
  37.  
  38.    if (((x1 - x2) * (Py - y2)) >= ((y1 - y2) * (Px - x2)))
  39.       return 1;
  40.    return 0;
  41. }
  42.  
  43.  
  44. /* This function returns TRUE it the player is on the right
  45.  * of the line segment created by the vertexes indexed by from, and to.
  46.  */
  47.  
  48. char OnRightLine(short from, short to)
  49. {
  50.    long x1, y1, x2, y2;
  51.    vertex *Vertex;
  52.    
  53.    Vertex = &Vertex_Array[from];
  54.    x1 = Vertex->x;
  55.    y1 = Vertex->y;
  56.    Vertex = &Vertex_Array[to];
  57.    x2 = Vertex->x;
  58.    y2 = Vertex->y;
  59.  
  60.    if (((x1 - x2) * (Py - y2)) >= ((y1 - y2) * (Px - x2)))
  61.       return 1;
  62.    return 0;
  63. }
  64.  
  65. /* Note concerning LeftSideInCone & RightSideInCone.
  66.  * These functions are based on the quadrants that the
  67.  * view cone intersects.  The minimum resolution is an
  68.  * entire quadrant.  This is not very accurate, and therefore
  69.  * does not cull out as many nodes as would be ideal, but it
  70.  * is a quick and dirty method that is fairly effective.
  71.  * It could DEFINATELY be improved upon.
  72.  
  73.  * This function returns TRUE if the LEFT Child Node
  74.  * of the node indexed by node_num is in the view cone.
  75.  */
  76.  
  77. char LeftSideInCone(short node_num)
  78. {
  79.    if ( LeftAngle < 0x4000 ) {
  80.       if (PNode_Array[node_num]->lx2 > Px)
  81.          return 1;
  82.    } else if (LeftAngle < 0x8000) {
  83.       if (PNode_Array[node_num]->ly2 > Py)
  84.          return 1;
  85.    } else if (LeftAngle < 0xC000) {
  86.       if (PNode_Array[node_num]->lx1 < Px)
  87.          return 1;
  88.    } else {
  89.       if (PNode_Array[node_num]->ly1 < Py)
  90.          return 1;
  91.    }
  92.  
  93.    return 0;
  94. }
  95.  
  96. /* This function returns TRUE if the RIGHT Child Node
  97.  * of the node indexed by node_num is in the view cone.
  98.  */
  99.  
  100. char RightSideInCone(short node_num)
  101. {
  102.    if (LeftAngle < 0x4000) {
  103.       if (PNode_Array[node_num]->rx2 > Px)
  104.          return 1;
  105.    } else if (LeftAngle < 0x8000) {
  106.       if (PNode_Array[node_num]->ry2 > Py)
  107.          return 1;
  108.    } else if (LeftAngle < 0xC000) {
  109.       if (PNode_Array[node_num]->rx1 < Px)
  110.          return 1;
  111.    } else {
  112.       if (PNode_Array[node_num]->ry1 < Py)
  113.          return 1;
  114.    }
  115.  
  116.    return 0;
  117. }
  118.  
  119. /**********************/
  120. /* This function obtains data common to all segs in the SSector
  121.  * as well as doing the backface elimination via OnRight.
  122.  */
  123.  
  124. short SetPlayerSSector(short SS, short *ssector, short *height)
  125. {
  126.    short LineSide, Sector;
  127.    segment *ThisSeg;
  128.    sector  *ThisSector;
  129.  
  130.    ThisSeg = &Seg_Array[SSector_Array[SS].first_seg];
  131.  
  132.    LineSide = ThisSeg->line_side;
  133.  
  134. #ifdef __GNUC__
  135.    Sector   = Side_Array[Line_Array[ThisSeg->line].side[LineSide]].sector;
  136. #else
  137.    Sector   = Side_Array[Line_Array[ThisSeg->xline].side[LineSide]].sector;
  138. #endif
  139.  
  140. /* Load the floor and ceiling height. */
  141.  
  142.    ThisSector = &Sector_Array[Sector];
  143.  
  144. /* ThisSector might be better below */
  145.    *ssector = SS;    /* Used to stop wall pass-through */
  146.    *height = ThisSector->floor_ht;
  147. }
  148.  
  149. short FindNode(short node_num, short *ssector, short *height)
  150. {
  151. /* If this node is a SSECTOR then we've found the player. */
  152.  
  153.    if (node_num & 0x8000) {
  154.       SetPlayerSSector(node_num & 0x7fff, ssector, height);
  155.       return;
  156.    }
  157.  
  158.    if (!OnRightNode(node_num)) {
  159.       if (LeftSideInCone(node_num))
  160.          FindNode(PNode_Array[node_num]->left, ssector, height);
  161.       else if (RightSideInCone(node_num))
  162.          FindNode(PNode_Array[node_num]->right, ssector, height);
  163.    } else {
  164.       if (RightSideInCone(node_num))
  165.          FindNode(PNode_Array[node_num]->right, ssector, height);
  166.       else if (LeftSideInCone(node_num))
  167.          FindNode(PNode_Array[node_num]->left, ssector, height);
  168.    }
  169. }
  170.  
  171.  
  172. /* This function sets the view's x,y, height, and angle values. */
  173.  
  174. void SetView(short *xi, short *yi, short *hi, unsigned short *ai)
  175. {
  176.    short old_px, old_py, x, y, h;
  177.    unsigned short old_pangle, a;
  178.    static start = 2;
  179. #ifdef __GNUC__
  180.    short ssector, height;
  181. #else
  182.    short s_sector, height;
  183. #endif
  184.  
  185.    x = *xi;
  186.    y = *yi;
  187.    h = *hi;
  188.    a = *ai;
  189.    
  190.    old_px = Px;
  191.    old_py = Py;
  192.    old_pangle = Pangle;
  193.    Px = x;
  194.    Py = y;
  195.    Ph = h;
  196.    Pangle = a;
  197.    LeftAngle = Pangle + 0x2000;
  198.  
  199. /* It's probably possible to find out the new sector by simply
  200.  * searching for the line that was crossed and enter the structures
  201.  * from there.
  202.  */
  203.  
  204.    if (start != 2) {    /* SetView not called from OpenWAD */
  205. #ifdef __GNUC__
  206.       ssector = -1;
  207.       FindNode(MaxNode, &ssector, &height);
  208.       if (ssector == -1) {
  209. #else
  210.       FindNode(MaxNode, &s_sector, &height);
  211.       if (s_sector == -1) {
  212. #endif
  213.          printf("Didn't find current ssector!\n");
  214.          exit(1);
  215.       }
  216.    }
  217.    if (start) {
  218.       start--;     /* The very first call here after loading is OK */
  219.       last_height = height;
  220. #ifdef __GNUC__
  221.       player_ssector = ssector;
  222.       printf("You start in sector %d at height %d\n", (int)ssector, (int)height);
  223. #else
  224.       player_ssector = s_sector;
  225.       printf("You start in sector %d at height %d\n", (int)s_sector, (int)height);
  226. #endif
  227.    } else {
  228. #ifdef __GNUC__
  229.       if (player_ssector != ssector) {
  230.          if (tellsect)
  231.             printf("Entering new sector %d at height %d\n", (int)ssector, (int)height);
  232. #else
  233.       if (player_ssector != s_sector) {
  234.          if (tellsect)
  235.             printf("Entering new sector %d at height %d\n", (int)s_sector, (int)height);
  236. #endif
  237.          if ((height - last_height <= STEP_HEIGHT) || !chksect) {
  238.             last_height = height;
  239. #ifdef __GNUC__
  240.             player_ssector = ssector;
  241. #else
  242.             player_ssector = s_sector;
  243. #endif
  244.          } else {
  245.             if (tellsect)
  246.                printf("Disallowed height difference!\n");
  247.             Px = old_px;
  248.             Py = old_py;
  249.             Pangle = old_pangle;
  250.             LeftAngle = Pangle + 0x2000;    
  251.          }
  252.       }
  253.    }
  254.  
  255.    SinPangle = sine(0x00-Pangle);
  256.    CosPangle = cosine(0x00-Pangle);
  257.    *xi = Px;
  258.    *yi = Py;
  259.    *hi = Ph;
  260.    *ai = Pangle;
  261. }
  262.  
  263. #if 0
  264. /* This function updates the view's x,y, height, and angle values. */
  265.  
  266. void UpdateView(short dx, short dy, short dh, unsigned short da)
  267. {
  268.    Px += dx;
  269.    Py += dy;
  270.    Ph += dh;
  271.    Pangle += da;
  272.    LeftAngle = Pangle + 0x2000;
  273.    SinPangle = sine(0x00-Pangle);
  274.    CosPangle = cosine(0x00-Pangle);
  275. }
  276. #endif
  277.  
  278.  
  279. /* This function returns the view's x,y height and angle values. */
  280.  
  281. void GetView(short *x, short *y, short *h, unsigned short *a)
  282. {
  283.    *x = Px;
  284.    *y = Py;
  285.    *h = Ph;
  286.    *a = Pangle;
  287. }
  288.